package ewa

import (
	"fmt"
	//"bytes"; "encoding/json"  
	"github.com/garyburd/redigo/redis"
)

/*************************************************************************************
rpush(key, value)：在名称为key的list尾添加一个值为value的元素
lpush(key, value)：在名称为key的list头添加一个值为value的 元素
llen(key)：返回名称为key的list的长度
lrange(key, start, end)：返回名称为key的list中start至end之间的元素
lindex(key, index)：返回名称为key的list中index位置的元素
lset(key, index, value)：给名称为key的list中index位置的元素赋值
lrem(key, count, value)：删除count个key的list中值为value的元素
lpop(key)：返回并删除名称为key的list中的首元素
rpop(key)：返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout)：lpop命令的block版本。
brpop(key1, key2,… key N, timeout)：rpop的block版本。
**************************************************************************************/

type RedisConnArgs struct {
	Qname string
	Network string
	Address string
	Password string
}

func CreateRedisConn(conn RedisConnArgs) redis.Conn {
	var err error
	var c redis.Conn
	if(len(conn.Password)==0){
		c, err = redis.Dial(conn.Network, conn.Address)
	}else {
		c, err = redis.Dial(conn.Network, conn.Address, redis.DialPassword(conn.Password))
	}

	if err != nil {
		l:=fmt.Sprintf("---Redis/> connect to redis error, %v", err); Log(l)
		return nil
	}

	return c
}

func RemoveRedisConn(c redis.Conn) {
	c.Close()
}

func RedisQlPush(c redis.Conn, queue string, value string) {
	_, err := c.Do("lpush", queue, value)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lpush failed, %v", err); Log(l)
	}
}

func RedisQrPush(c redis.Conn, queue string, value string) {
	_, err := c.Do("rpush", queue, value)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> rpush failed, %v", err); Log(l)
	}
}

func RedisQlLen(c redis.Conn, queue string) int {
	num, err := c.Do("llen", queue)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> llen failed, %v", err); Log(l)
		return 0
	} else {
		l:=fmt.Sprintf("---Redis/> llen, [%d]", num); Log(l)
		return num.(int)
	}
}

func RedisQlRange(c redis.Conn, queue string, start int, end int) []string {
	values, err := redis.Values(c.Do("lrange", queue, start, end))
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lrange failed, %v", err); Log(l)
	}
	
	val := make([]string, (end-start+1))
	var i int=0
	for _, v := range values {
		//fmt.Printf(" %s ", v.([]byte))
		val[i] = string(v.([]byte))
		i++
	}
	//fmt.Printf("\n")
	return val
}


func RedisQlIndex(c redis.Conn, queue string, idx int) string {
	val, err := c.Do("lindex", queue, idx)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lindex failed, %v", err); Log(l)
		return ""
	} else {
		l:=fmt.Sprintf("---Redis/> lindex [%d] value:[%s]", idx, val); Log(l)
		return val.(string)
	}
}

func RedisQlSet(c redis.Conn, queue string, idx int, value string) {
	_, err := c.Do("lset", queue, idx, value)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lset failed, %v", err); Log(l)
	}
}

func RedisQlRemove(c redis.Conn, queue string, cnt int, value string) {
	_, err := c.Do("lrem", queue, cnt, value)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lrem failed, %v", err); Log(l)
	}
}

func RedisQlPop(c redis.Conn, queue string) string {
	val, err := c.Do("lpop", queue)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> lpop failed, %v", err); Log(l)
		return ""
	}else{
		return val.(string)
	}
}

func RedisQrPop(c redis.Conn, queue string) string {
	val, err := c.Do("rpop", queue)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> rpop failed, %v", err); Log(l)
		return ""
	}else{
		return val.(string)
	}
}

func RedisQbLPop(c redis.Conn, queue string, timeout int) string {
	res, err := c.Do("blpop", queue, timeout)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> blpop failed, %v", err); Log(l)
		return ""
	} else {
		return res.(string)
	}	
}

func RedisQbRPopStr(c redis.Conn, queue string, timeout int) string {
	res, err := c.Do("brpop", queue, timeout)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> brpop failed, %v", err); Log(l)
		return ""
	} else {
		return res.(string)
	}	
}


func RedisQbRPop(c redis.Conn, queue string, timeout int) []interface{} {
	messageJSON, err := c.Do("brpop", queue, timeout)
	if err != nil {
		l:=fmt.Sprintf("---Redis/> blpop failed, %v", err); Log(l)
		return nil
	} else {
		//fmt.Println(messageJSON)
		if messageJSON != nil{
			return messageJSON.([]interface{})
		}else{
			return nil
		}
	}	
}